#pragma once
#include <string.h>
//das ist ein test... todo delete me

#undef EOF
static const int EOF = -1;
static const int MAX_INT = 2147483647;


//class Hash{};
typedef int Hash;

//class Key{};
typedef long long Key;

class Information{
public:
    //declare members pubilc for convenience
    char* lexem;
    enum TType type;


    Information(char* lexem, TType type) :
        lexem(lexem),
        type(type)
    {
    }
};

class Lexem{

    char* chars;

    //the length of the string, including the trailing '\0'
    size_t length;

public:
    Lexem(char* chars, size_t len) :
      chars(chars),
      length(len)
    {
    }

    char* getChars()
    {
        return chars;
    }

    size_t getLength()
    {
        return length;
    }
};


//class TType{};
//typedef int TType;
enum TType{
    NO_TYPE,
    TEST_TYPE,
    TOK_SIGN,
    TOK_SPECIAL,
    TOK_INT,
    TOK_IDENT,
    TOK_COMMENT
};

union TokenData{
    Key asKey; //for TOK_IDENT
    int asInt; //for TOK_INT
    char asChar; //for TOK_SIGN
};

class Token{
    TType type;
    unsigned int line;
    unsigned int column;
    TokenData data;

public:

    Token(TType type, int line, int column, TokenData data) :
        type(type),
        line(line),
        column(column),
        data(data)
    {
    }

    TType getType()   { return type;         }
    int   getLine()   { return line;         }
    int   getColumn() { return column;       }
    Key   getKey()    { return data.asKey;   }
    int   getInt()    { return data.asInt;   }
    char  getChar()   { return data.asChar;  }
    
};



class Helper
{
public:
    static bool Helper::isNumerical(char c)
    {
        if('0' <= c && c <= '9')
            return true;
        return false;
    }

    static bool Helper::isAlpha(char c)
    {
        if('a' <= c && c <= 'z' ||
           'A' <= c && c <= 'Z')
            return true;
        return false;
    }

    static bool Helper::isSign(char c)
    {
        switch(c)
        {
            case '+':
            case '-':
            case '/':
            case '*':
            case '<':
            case '>':
            case '=':
            //case '<!>':
            case '!':
            case '&':
            case ';':
            case '(':
            case ')':
            case '{':
            case '}':
            case '[':
            case ']':
                return true;
        }

        return false;
    }

    static bool Helper::isSpace(char c)
    {
        if(c == ' ')
            return true;
        if(c == '\t')
            return true;
        if(c == '\n')//CR for Windows operating systems only
            return true;
        if(c == '\r')
            return true;

        return false;
    }
};
